#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
配置管理模块 - 负责JSON配置文件的读写操作
遵循单一职责原则，专门处理配置数据的管理

Copyright (c) 2025 RAYA-MAX
Quick-Start is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan
PSL v2.
You may obtain a copy of Mulan PSL v2 at:
         http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY
KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
"""

import json
import os
import sys
from typing import Dict, List, Any, Optional


class ConfigManager:
    """配置管理器类 - 处理应用程序配置的读写"""
    
    def __init__(self, config_file: str = "config.json"):
        """
        初始化配置管理器

        Args:
            config_file: 配置文件路径
        """
        # 获取程序所在目录，确保配置文件在exe文件同级目录
        if getattr(sys, 'frozen', False):
            # 如果是打包后的exe文件
            app_dir = os.path.dirname(sys.executable)
        else:
            # 如果是Python脚本
            app_dir = os.path.dirname(os.path.abspath(__file__))

        # 配置文件的完整路径
        self.config_file = os.path.join(app_dir, config_file)
        self.config_data = self._load_config()
    
    def _load_config(self) -> Dict[str, Any]:
        """
        加载配置文件，如果不存在则创建默认配置
        
        Returns:
            配置数据字典
        """
        if os.path.exists(self.config_file):
            try:
                with open(self.config_file, 'r', encoding='utf-8') as f:
                    return json.load(f)
            except (json.JSONDecodeError, IOError) as e:
                print(f"配置文件读取失败: {e}")
                return self._create_default_config()
        else:
            return self._create_default_config()
    
    def _create_default_config(self) -> Dict[str, Any]:
        """
        创建默认配置
        
        Returns:
            默认配置数据
        """
        default_config = {
            "modes": {
                "工作模式": {
                    "name": "工作模式",
                    "software_list": []
                },
                "游戏模式": {
                    "name": "游戏模式", 
                    "software_list": []
                },
                "休闲模式": {
                    "name": "休闲模式",
                    "software_list": []
                }
            },
            "current_mode": "工作模式"
        }
        self._save_config(default_config)
        return default_config
    
    def _save_config(self, config_data: Optional[Dict[str, Any]] = None) -> bool:
        """
        保存配置到文件
        
        Args:
            config_data: 要保存的配置数据，如果为None则保存当前配置
            
        Returns:
            保存是否成功
        """
        try:
            data_to_save = config_data if config_data is not None else self.config_data
            with open(self.config_file, 'w', encoding='utf-8') as f:
                json.dump(data_to_save, f, ensure_ascii=False, indent=2)
            return True
        except IOError as e:
            print(f"配置文件保存失败: {e}")
            return False
    
    def get_modes(self) -> List[str]:
        """
        获取所有模式名称列表
        
        Returns:
            模式名称列表
        """
        return list(self.config_data.get("modes", {}).keys())
    
    def get_current_mode(self) -> str:
        """
        获取当前选中的模式
        
        Returns:
            当前模式名称
        """
        return self.config_data.get("current_mode", "工作模式")
    
    def set_current_mode(self, mode_name: str) -> bool:
        """
        设置当前模式
        
        Args:
            mode_name: 模式名称
            
        Returns:
            设置是否成功
        """
        if mode_name in self.config_data.get("modes", {}):
            self.config_data["current_mode"] = mode_name
            return self._save_config()
        return False
    
    def add_mode(self, mode_name: str) -> bool:
        """
        添加新模式
        
        Args:
            mode_name: 新模式名称
            
        Returns:
            添加是否成功
        """
        if mode_name and mode_name not in self.config_data.get("modes", {}):
            self.config_data["modes"][mode_name] = {
                "name": mode_name,
                "software_list": []
            }
            return self._save_config()
        return False
    
    def delete_mode(self, mode_name: str) -> bool:
        """
        删除模式
        
        Args:
            mode_name: 要删除的模式名称
            
        Returns:
            删除是否成功
        """
        if mode_name in self.config_data.get("modes", {}) and len(self.config_data["modes"]) > 1:
            del self.config_data["modes"][mode_name]
            # 如果删除的是当前模式，切换到第一个可用模式
            if self.config_data.get("current_mode") == mode_name:
                self.config_data["current_mode"] = list(self.config_data["modes"].keys())[0]
            return self._save_config()
        return False
    
    def rename_mode(self, old_name: str, new_name: str) -> bool:
        """
        重命名模式
        
        Args:
            old_name: 原模式名称
            new_name: 新模式名称
            
        Returns:
            重命名是否成功
        """
        if (old_name in self.config_data.get("modes", {}) and 
            new_name and new_name not in self.config_data["modes"]):
            
            # 保存原模式数据
            mode_data = self.config_data["modes"][old_name].copy()
            mode_data["name"] = new_name
            
            # 删除原模式，添加新模式
            del self.config_data["modes"][old_name]
            self.config_data["modes"][new_name] = mode_data
            
            # 更新当前模式名称
            if self.config_data.get("current_mode") == old_name:
                self.config_data["current_mode"] = new_name
                
            return self._save_config()
        return False
    
    def get_software_list(self, mode_name: str) -> List[Dict[str, Any]]:
        """
        获取指定模式的软件列表
        
        Args:
            mode_name: 模式名称
            
        Returns:
            软件列表
        """
        mode_data = self.config_data.get("modes", {}).get(mode_name, {})
        return mode_data.get("software_list", [])
    
    def add_software(self, mode_name: str, software_info: Dict[str, str]) -> bool:
        """
        向指定模式添加软件
        
        Args:
            mode_name: 模式名称
            software_info: 软件信息字典，包含name, path, description
            
        Returns:
            添加是否成功
        """
        if mode_name in self.config_data.get("modes", {}):
            self.config_data["modes"][mode_name]["software_list"].append(software_info)
            return self._save_config()
        return False
    
    def update_software(self, mode_name: str, index: int, software_info: Dict[str, str]) -> bool:
        """
        更新指定模式中的软件信息
        
        Args:
            mode_name: 模式名称
            index: 软件在列表中的索引
            software_info: 新的软件信息
            
        Returns:
            更新是否成功
        """
        if (mode_name in self.config_data.get("modes", {}) and 
            0 <= index < len(self.config_data["modes"][mode_name]["software_list"])):
            self.config_data["modes"][mode_name]["software_list"][index] = software_info
            return self._save_config()
        return False
    
    def delete_software(self, mode_name: str, index: int) -> bool:
        """
        删除指定模式中的软件
        
        Args:
            mode_name: 模式名称
            index: 软件在列表中的索引
            
        Returns:
            删除是否成功
        """
        if (mode_name in self.config_data.get("modes", {}) and 
            0 <= index < len(self.config_data["modes"][mode_name]["software_list"])):
            del self.config_data["modes"][mode_name]["software_list"][index]
            return self._save_config()
        return False
